#include "MSerialThread.h"
#define cout        qDebug()
#define tr          QString::fromLocal8Bit


MSerialThread::MSerialThread(int id)
    : MBaseSerialThread(id)
{
    m_pSerial   = NULL;

    m_serialConfig.serialBaudrate  = BAUD9600;
    m_serialConfig.serialDatabits  = DATA_8;
    m_serialConfig.serialStopbits  = STOP_1;
    m_serialConfig.serialParity    = PAR_NONE;
    m_serialConfig.serialFlow      = FLOW_OFF;
}

MSerialThread::~MSerialThread()
{
    close();
}

void MSerialThread::setup(QHash<QString, QString> config)
{
    m_serialConfig.serialBaudrate = (BaudRateType)config.value(tr("波特率"),"9600").toInt();
    m_serialConfig.serialDatabits = (DataBitsType)(config.value(tr("数据位"),"5").toInt()-5);
    QHash<QString,int> stopBitsHash;
    stopBitsHash["1"]   =0;
    stopBitsHash["1.5"] =1;
    stopBitsHash["2"]   =2;
    m_serialConfig.serialStopbits = (StopBitsType)stopBitsHash[config.value(tr("停止位"),"1")];
    QHash<QString,int> parityHash;
    parityHash["NONE"]  =0;
    parityHash["ODD"]   =1;
    parityHash["EVEN"]  =2;
    parityHash["MARK"]  =3;
    parityHash["SPACE"] =4;
    m_serialConfig.serialParity = (ParityType)parityHash[config.value(tr("校验位"),"NONE")];
    QHash<QString,int> flowHash;
    flowHash["OFF"]     =0;
    flowHash["HARDWARE"]=1;
    flowHash["XONXOFF"] =2;
    m_serialConfig.serialFlow = (FlowType)flowHash[config.value(tr("流控"),"OFF")];
}

bool MSerialThread::isOpen()
{
    if(m_pSerial == NULL)
    {
        return false;
    }

    return m_pSerial->isOpen();
}

int MSerialThread::initSerial(QVariant channel,QVariantVector /*subdivision*/)
{
    if(isOpen())
    {
        m_serialConfig.serialBaudrate  = m_pSerial->baudRate();
        m_serialConfig.serialDatabits  = m_pSerial->dataBits();
        m_serialConfig.serialStopbits  = m_pSerial->stopBits();
        m_serialConfig.serialParity    = m_pSerial->parity();
        m_serialConfig.serialFlow      = m_pSerial->flowControl();
        close();
    }

    m_pSerial = new Win_QextSerialPort( "\\\\.\\"+channel.toString() , QextSerialBase::EventDriven );

    if(!m_pSerial->open(QIODevice::ReadWrite) ) //打开串口
    {
        delete m_pSerial;
        m_pSerial = NULL;
        emit serialOpen(false);
        lastError = ERROR_SERIAL_OPEN;
        return lastError;
    }

    //配置
    m_pSerial->setBaudRate(m_serialConfig.serialBaudrate);
    m_pSerial->setDataBits(m_serialConfig.serialDatabits);
    m_pSerial->setStopBits(m_serialConfig.serialStopbits);
    m_pSerial->setParity(m_serialConfig.serialParity);
    m_pSerial->setFlowControl(m_serialConfig.serialFlow);

//    cout << "&&&" << serialName << serialBaudrate << serialDatabits << serialStopbits << serialParity << serialFlow;
//    cout << "###" << m_pSerial->portName() << m_pSerial->baudRate() << m_pSerial->dataBits() << m_pSerial->stopBits() << m_pSerial->parity() << m_pSerial->flowControl();

    emit serialOpen(true);
    lastError = ERROR_SUCCESS;
    return lastError;
}

// 关闭串口
void MSerialThread::close()
{
    if(m_pSerial == NULL)//如果已经处于关闭状态，则返回
        return;

    if (m_pSerial->isOpen())
    {
        m_pSerial->close();
    }

    emit serialOpen(false);
    delete m_pSerial;
    m_pSerial = NULL;//重置串口指针至出事状态
    lastError = ERROR_SERIAL_CLOSE;
}

int MSerialThread::write(QByteArray &ucDataArray, int id)
{
    if(m_pSerial == NULL)
    {
        return ERROR_SERIAL_INIT;
    }

    if (!m_pSerial->isOpen())
    {
        if(!m_pSerial->open(QIODevice::ReadWrite) ) //打开串口
        {
            return ERROR_SERIAL_INIT;
        }
    }

    //cout << "###" << m_pSerial->portName() << m_pSerial->baudRate() << m_pSerial->dataBits() << m_pSerial->stopBits() << m_pSerial->parity() << m_pSerial->flowControl();
    emit signal_initialData(true,ucDataArray,getTimeStamp());

    int rlt = (int)m_pSerial->write(ucDataArray);

    return rlt;
}

void MSerialThread::run()
{
    m_bStopped      = true;
    int nAvailable  = 0;

    QByteArray  m_arrBuffer;
    m_arrBuffer.clear();

    while(m_bStopped && this->isOpen()) //如果串口被成功初始化并且正确打开，否则就结束。
    {

            //定时1ms
            timeBeginPeriod(1);
            Sleep(1);
            timeEndPeriod(1);

        nAvailable = m_pSerial->bytesAvailable();
        if(nAvailable > 0)
        {
            m_arrBuffer.append(m_pSerial->readAll());

            if(m_arrBuffer.size() > 0)
            {
                emit signal_initialData(false,m_arrBuffer, getTimeStamp());

                m_arrBuffer.clear();
            }
        }
    }
    m_bStopped = false;
}
